package com.tuanzi.loan.business.repository.businesssystem.impl;

import com.tuanzi.loan.business.entity.businesssystem.BusinessMain;
import com.tuanzi.loan.business.repository.businesssystem.custom.BusinessMainRepositoryCustom;
import com.tuanzi.loan.core.repository.JOOQBaseRepositoryPlus;
import com.tuanzi.loan.generated.jooq.loan.tables.LoanBusinessChannelMain;
import com.tuanzi.loan.generated.jooq.loan.tables.LoanBusinessPrepay;
import com.tuanzi.loan.vo.request.businesssystem.BusinessMainRequest;
import com.tuanzi.loan.vo.response.businesssystem.BusinessMainResponse;
import org.jooq.impl.DSL;
import org.jooq.impl.TableImpl;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import static com.tuanzi.loan.generated.jooq.loan.tables.LoanBusinessBill.LOAN_BUSINESS_BILL;
import static com.tuanzi.loan.generated.jooq.loan.tables.LoanBusinessChannelMain.LOAN_BUSINESS_CHANNEL_MAIN;
import static com.tuanzi.loan.generated.jooq.loan.tables.LoanBusinessIncome.LOAN_BUSINESS_INCOME;
import static com.tuanzi.loan.generated.jooq.loan.tables.LoanBusinessPrepay.LOAN_BUSINESS_PREPAY;

public class BusinessMainRepositoryImpl extends JOOQBaseRepositoryPlus implements BusinessMainRepositoryCustom {
	@Override
	protected TableImpl getTable() {
		return LOAN_BUSINESS_CHANNEL_MAIN;
	}

	@Override
	public Page<BusinessMainResponse> list(BusinessMainRequest searchRequest, Pageable pageable) {

		String companyName = searchRequest.getMainName();
		Integer mainType = searchRequest.getMainType();
		Date startTime = searchRequest.getStartTime();
		Date endTime = searchRequest.getEndTime();
		String creator = searchRequest.getCreator();
		LoanBusinessChannelMain channelMain = LOAN_BUSINESS_CHANNEL_MAIN;
		LoanBusinessPrepay prepay = LOAN_BUSINESS_PREPAY;
		fields(channelMain.fields());
		fields(DSL.sum(prepay.PREPAY_AMOUNT).filterWhere(prepay.PAY_TYPE.eq((byte) 0)).as("advance_pay"),
				DSL.sum(prepay.PREPAY_AMOUNT).filterWhere(prepay.PAY_TYPE.eq((byte) 1).or(prepay.PAY_TYPE.eq((byte) 2))).as("prepay"),
				DSL.sum(prepay.PREPAY_AMOUNT).filterWhere(prepay.PAY_TYPE.eq((byte) 3)).as("return_pay"),
				DSL.sum(prepay.PREPAY_AMOUNT).filterWhere(prepay.PAY_TYPE.eq((byte) 4)).as("refund_pay"));
		if (startTime != null && endTime != null) {
			java.sql.Date minValue = new java.sql.Date(startTime.getTime());
			java.sql.Date maxValue = new java.sql.Date(endTime.getTime());
			leftJoin(prepay, prepay.COMPANY_ID.eq(channelMain.ID).and(prepay.PREPAY_TIME.between(minValue, maxValue)));
		} else {
			leftJoin(prepay, prepay.COMPANY_ID.eq(channelMain.ID));
		}
		contains(channelMain.CHANNEL_MAIN, companyName);
		contains(channelMain.MAIN_TYPE, mainType);
		eq(channelMain.CREATOR,creator);
		groupBy(channelMain.ID);
		orderBy(channelMain.CREATE_TIME, Sort.Direction.DESC);
		Page<BusinessMainResponse> search = search(pageable, record -> {
			BusinessMainResponse response = new BusinessMainResponse();
			Integer id = record.get(channelMain.ID);
			response.setId(id);
			response.setCompanyName(record.get(channelMain.CHANNEL_MAIN));
			response.setMainType(record.get(channelMain.MAIN_TYPE) == null ? 0 : record.get(channelMain.MAIN_TYPE).intValue());
			response.setIdCode(record.get(channelMain.IDCODE));
			response.setBank(record.get(channelMain.BANK));
			response.setBankId(record.get(channelMain.BANK_ID));
			response.setPrepayAmount(new BigDecimal(record.get("prepay", Double.class)==null?0:record.get("prepay", Double.class))
					.subtract(new BigDecimal(record.get("refund_pay", Double.class)==null?
							0:record.get("refund_pay", Double.class))).doubleValue());
			response.setAdvancePay(record.get("advance_pay", Double.class));
			response.setReturnPay(record.get("return_pay", Double.class));
			response.setExpendAmount(getExpandAmount(id, searchRequest));
			response.setBillAmount(getBillAmount(id, searchRequest));
			response.setRemark(record.get(channelMain.REMARK));
			response.setCreator(record.get(channelMain.CREATOR));
			response.setCreateTime(record.get(channelMain.CREATE_TIME));
			return response;
		});
		return search;
	}

	@Override
	public List<BusinessMain> getCompanyList() {
		fields(LOAN_BUSINESS_CHANNEL_MAIN.ID, LOAN_BUSINESS_CHANNEL_MAIN.CHANNEL_MAIN);
		List<BusinessMain> search = search(BusinessMain.class);
		return search;
	}

	@Override
	public void updateExpendAmount(Long companyId, Double expendAmount) {
		dslContext.update(LOAN_BUSINESS_CHANNEL_MAIN).set(LOAN_BUSINESS_CHANNEL_MAIN.EXPEND_AMOUNT, expendAmount).where(LOAN_BUSINESS_CHANNEL_MAIN.ID.eq(companyId.intValue()));
	}

	@Override
	public void updatePrepayAmount(Long companyId, Double prepayAmount) {
		dslContext.update(LOAN_BUSINESS_CHANNEL_MAIN).set(LOAN_BUSINESS_CHANNEL_MAIN.PREPAY_AMOUNT, prepayAmount).where(LOAN_BUSINESS_CHANNEL_MAIN.ID.eq(companyId.intValue()));
	}

	@Override
	public void updatebillAmount(Long companyId, Double billAmount) {
		dslContext.update(LOAN_BUSINESS_CHANNEL_MAIN).set(LOAN_BUSINESS_CHANNEL_MAIN.BILL_AMOUNT, billAmount).where(LOAN_BUSINESS_CHANNEL_MAIN.ID.eq(companyId.intValue()));
	}

	private Double getExpandAmount(Integer companyId, BusinessMainRequest searchRequest) {
		Date startTime = searchRequest.getStartTime();
		Date endTime = searchRequest.getEndTime();
		if (startTime != null && endTime != null) {
			Double one = dslContext.select(DSL.sum(LOAN_BUSINESS_INCOME.INCOME_AMOUNT)).from(LOAN_BUSINESS_INCOME).where(LOAN_BUSINESS_INCOME.CHANNEL_MAIN_ID.eq(companyId))
					.and(LOAN_BUSINESS_INCOME.TIME.between(new java.sql.Date(startTime.getTime()), new java.sql.Date(endTime.getTime()))).fetchOne().into(Double.class);
			return one == null ? 0d : one;
		}

		Double one = dslContext.select(DSL.sum(LOAN_BUSINESS_INCOME.INCOME_AMOUNT)).from(LOAN_BUSINESS_INCOME).where(LOAN_BUSINESS_INCOME.CHANNEL_MAIN_ID.eq(companyId)).fetchOne()
				.into(Double.class);
		return one == null ? 0d : one;

	}

	private Double getBillAmount(Integer companyId, BusinessMainRequest searchRequest) {
		Date startTime = searchRequest.getStartTime();
		Date endTime = searchRequest.getEndTime();
		if (startTime != null && endTime != null) {
			Double one = dslContext.select(DSL.sum(LOAN_BUSINESS_BILL.BILL_AMOUNT)).from(LOAN_BUSINESS_BILL).where(LOAN_BUSINESS_BILL.COMPANY_ID.eq(Long.valueOf(companyId)))
					.and(LOAN_BUSINESS_BILL.BILL_DATE.between(new java.sql.Date(startTime.getTime()), new java.sql.Date(endTime.getTime()))).fetchOne().into(Double.class);
			return one == null ? 0d : one;
		}

		Double one = dslContext.select(DSL.sum(LOAN_BUSINESS_BILL.BILL_AMOUNT)).from(LOAN_BUSINESS_BILL).where(LOAN_BUSINESS_BILL.COMPANY_ID.eq(Long.valueOf(companyId))).fetchOne()
				.into(Double.class);
		return one == null ? 0d : one;

	}
}
